<!-- 业务组件：orc识别 -->
<template>
  <div class="upload-imag w-full" :class="{ 'upload-margin': margin }">
    <!-- 内容 -->
    <div class="upload-cont w-full">
      <a-upload
        v-model:file-list="uploadValue"
        :action="uploadAction"
        :data="appendData"
        :limit="1"
        name="files"
        with-credentials
        :auto-upload="false"
        ref="uploadRef"
        multiple
        @change="uploadChange"
        @before-upload="beforeUpload"
        @exceed-limit="exceedLimit"
      >
        <template #upload-button>
          <div class="upload-btn">
            <a-button type="primary">
              <template #icon>
                <icon-upload />
              </template>
              点击上传
            </a-button>
          </div>
        </template>
        <template #upload-item="{ fileItem, index }">
          <section class="upload-content" :key="index">
            <a-link
              class="recognition flex"
              :loading="loadingVisible"
              :hoverable="false"
              @click="driveCardFn"
              v-if="ocrType && userStore.epOcrSwitch"
              :disabled="fileItem.status != 'done'"
            >
              <icon-scan />
              <span>图片识别</span>
            </a-link>
            <div class="file" @click.stop="previewFn(fileItem)">
              <div class="icon">
                <img :src="fileItem.url" alt="" />
              </div>
              <a-typography-text class="name" :ellipsis="{ showTooltip: true }">
                {{ fileItem.name }}
              </a-typography-text>
            </div>
            <div class="action">
              <!-- 进度条 -->
              <div class="progress" v-if="['uploading', 'init'].includes(fileItem.status)">
                {{ fileItem.status == 'init' ? '压缩中' : '上传中' }}
                <!-- 压缩进度条 -->
                <a-progress v-if="fileItem.status == 'init'" size="mini" :percent="fileItem.percent" />
                <!-- 上传进度条 -->
                <a-progress v-if="fileItem.status == 'uploading'" size="mini" :percent="fileItem.percent" />
              </div>
              <a-popconfirm content="是否确认删除？" type="warning" @ok="delItem(index)">
                <icon-delete class="del-text" />
              </a-popconfirm>
            </div>
          </section>
        </template>
      </a-upload>
    </div>
    <a-image-preview :src="previewList" v-model:visible="previewVisible" />
  </div>
</template>

<script setup lang="ts">
  import { ref, watch } from 'vue'
  import { useRoute } from 'vue-router'
  import { Message } from '@arco-design/web-vue'
  import { getFileInfo } from '@/api/common/index.js'
  import useUserStore from '@/store/modules/user'
  import {
    resolveDrivingLicense,
    resolveBackDrivingLicense,
    resolveBusinessLicense,
    resolveIdCardFront,
    resolveIdCardBack,
    resolveInspection,
  } from '@/api/market/member'
  import MyCompress from './scripts/upload-compress'

  // 获取商户配置详情
  const userStore = useUserStore()
  // 获取商户详情不应该放到当前组件内部，组件可能有多个实例，放到这里可能会调用多次
  // userStore.setEpDetail()

  // 预览图片
  const previewVisible = ref(false)
  const previewList = ref('')
  // 双向绑定值
  const uploadValue: any = ref([])

  // 图片识别loading
  const loadingVisible = ref(false)

  const route = useRoute()

  const props = defineProps({
    modelValue: {
      type: [Array<string>],
    },
    ocrType: {
      // 行驶证正面：font
      // 行驶证反面：back
      // 营业执照：license
      // 身份证正面：cardFrontFileId
      // 身份证反面：cardBackFileId
      // 年检证：inspection
      type: String,
      default: '',
    },
    maxMB: {
      type: Number,
      default: 8,
    },
    limit: {
      type: Number,
      default: 1,
    },
    margin: Boolean,
    // 增加文件类型需要增加对应图标和预览方法
    types: {
      type: String,
      default: 'JPG、JPEG、PNG、WEBP',
    },
  })
  const emit = defineEmits(['update:modelValue', 'change', 'ocrClick'])

  const uploadAction = import.meta.env.VITE_BASE_PATH + '/uploadFile/commonUpload'
  const appendData = { remark: route.path }

  // 初始化 before
  const initValueWatch = watch(
    () => props.modelValue,
    (val) => {
      initValueFn(val)
    }
  )

  const initValueFn = (val: any) => {
    if (val) {
      // 由于此处需要获取文件名称，需要调用接口
      getFileInfo({ id: val }).then((res: any) => {
        const result = res.result
        uploadValue.value = [
          {
            uid: result.fileIdStr,
            name: result.originalFileName,
            status: 'done',
            url: `${import.meta.env.VITE_BASE_PATH}/uploadFile/image/${result.fileIdStr}`,
          },
        ]
      })
    }
    // 关闭watch
    initValueWatch && initValueWatch()
  }

  // 上传之前 限制格式
  const beforeUpload = (file: { size: number; name: String }) => {
    // 判断类型
    let isMatchedType = false
    props.types.split('、').forEach((item) => {
      if (file.name.toLocaleUpperCase().endsWith(item)) {
        isMatchedType = true
        return
      }
    })
    if (isMatchedType == false) {
      Message.warning(`请上传${props.types}格式文件`)
      return false
    }
    return true
  }

  // 触发emit事件
  const emitEvent = () => {
    const uploadedList = uploadValue.value.filter((item) => item.status == 'done')
    const ids = uploadedList.map((item: any) => item.uid)
    let res = ids[0]
    if (ids.length == 0) res = undefined

    emit('update:modelValue', res)
    emit('change', res)
  }

  // 删除
  const delItem = (index: number) => {
    uploadValue.value.splice(index, 1)
    emitEvent()
  }
  // 预览
  const previewFn = (fileItem: any) => {
    previewList.value = fileItem.url
    previewVisible.value = true
  }

  const uploadRef = ref()
  // 修改
  const uploadChange = (fileList: any, fileItem: any) => {
    // 文件初始化
    if (fileItem.status == 'init' && fileItem.percent == 0) {
      // 压缩图片
      MyCompress({
        fileItem: fileItem,
        success: (compressedFile: any) => {
          // 更新文件，调用 updateFile 方法
          uploadRef.value.updateFile(fileItem.uid, compressedFile)
          // 上传文件，调用 submit 方法
          uploadRef.value.submit(fileItem)
        },
      })
    } else if (fileItem.status == 'uploading') {
      if (fileItem.percent > 0.99) fileItem.percent = 0.99
    } else if (fileItem.status == 'done') {
      uploadValue.value = fileList.map((item: any) => {
        if (item.response) {
          item.uid = item.response.result[0].fileIdStr
          // item.url = `${import.meta.env.VITE_BASE_PATH}/uploadFile/image/${item.uid}`
        }
        return item
      })
      // 判断是否全部上传完毕，不存在初始化(压缩中)及上传中的文件
      const hasUploading = uploadValue.value.some((item: any) => ['init', 'uploading'].includes(item.status))
      if (!hasUploading) {
        emitEvent()
      }
    }
  }

  // OCR识别
  const driveCardFn = () => {
    loadingVisible.value = true
    let fn = resolveDrivingLicense
    // 行驶证正面
    if (props.ocrType == 'font') {
      fn = resolveDrivingLicense
    }
    // 行驶证反面
    if (props.ocrType == 'back') {
      fn = resolveBackDrivingLicense
    }
    // 营业执照
    if (props.ocrType == 'license') {
      fn = resolveBusinessLicense
    }
    // 正面照（人像）
    if (props.ocrType == 'cardFrontFileId') {
      fn = resolveIdCardFront
    }
    // 反面照（国徽）
    if (props.ocrType == 'cardBackFileId') {
      fn = resolveIdCardBack
    }
    // 年检证
    if (props.ocrType == 'inspection') {
      fn = resolveInspection
    }

    fn({ fileId: uploadValue.value[0].uid })
      .then((res: any) => {
        const result = res.result
        if (props.ocrType == 'inspection') {
          if (result && result.date) {
            emit('ocrClick', result)
          } else {
            // 未识别到 date
            Message.error('文件识别失败，请参考提示上传')
          }
        } else {
          emit('ocrClick', result)
        }
      })
      .finally(() => {
        loadingVisible.value = false
      })
  }

  const exceedLimit = () => {
    Message.warning(`超过最大数量，请重新选择`)
  }
  defineExpose({
    update: (id: String) => {
      emit('update:modelValue', id)
      if (id) {
        initValueFn(id)
      } else {
        uploadValue.value = []
      }
    },
  })
</script>

<style lang="less" scoped>
  .upload-imag {
    display: inline-block;
    background: #ffffff;
    position: relative;
    &.upload-margin {
      margin-top: 20px;
      margin-right: 20px;
      width: 100%;
    }
  }
  :deep(.arco-upload-list.arco-upload-list-type-picture-card) {
    flex-wrap: warp;
  }

  .upload-content {
    position: relative;
    width: 100%;
    height: 73px;
    background: #f7f8fa;
    border-radius: 2px 2px 2px 2px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    .recognition {
      position: absolute;
      top: -26px;
      right: 0;
      align-items: center;
      color: #1890ff;
      cursor: pointer;
      span {
        margin-left: 4px;
      }
    }
    .file {
      display: flex;
      align-items: center;
      cursor: pointer;
      flex: 1;
      height: 100%;
      overflow: hidden;
      .name {
        margin-left: 12px;
        width: 168px;
        // white-space: nowrap;
        // overflow: hidden;
        // text-overflow: ellipsis;
        flex: 1;
        margin-bottom: 0;
        cursor: pointer;
      }
      .icon {
        width: 40px;
        flex-shrink: 0;
        img {
          width: 40px;
        }
      }
    }
    .action {
      display: flex;
      align-items: center;
      .progress {
        margin-right: 10px;
      }
    }

    .del-text {
      cursor: pointer;
    }
  }
  .upload-btn {
    position: absolute;
    top: -5px;
    left: 0;
  }
  :deep(.arco-upload-list.arco-upload-list-type-text) {
    display: flex;
    justify-content: flex-start;
    flex-wrap: wrap;
  }
</style>
